package com.yangsir.mysite.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yangsir.mysite.Dto.VisitDto;
import com.yangsir.mysite.Dto.WeekDto;
import com.yangsir.mysite.common.R;
import com.yangsir.mysite.mapper.VisitcountMapper;
import com.yangsir.mysite.pojo.Visitcount;
import com.yangsir.mysite.service.ArticleService;
import com.yangsir.mysite.service.VisitcountService;
import com.yangsir.mysite.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
* @author yf
* @description 针对表【visitcount(记录网站的每日访问量)】的数据库操作Service实现
* @createDate 2024-07-27 19:56:31
*/
@Service
public class VisitcountServiceImpl extends ServiceImpl<VisitcountMapper, Visitcount>
    implements VisitcountService{
    @Resource
    private VisitcountMapper visitcountMapper;
    @Resource
    private ArticleService articleService;
    @Resource
    private RedisUtils redisUtils;

    private final String VISIT_COUNT_KEY = "visit_count";
    private final String VISIT_ALL_COUNT_KEY = "visit_all_count";
    private final String ARTICLE_COUNT_KEY = "article_count";

    @Value("${starttime.time}")
    private String startTime;
    @Override
    public R<VisitDto> visitData(HttpServletRequest httpServletRequest) {
        VisitDto visitDto = new VisitDto();
        visitDto.setStartTime(startTime);

        visitDto = checkIp(httpServletRequest, visitDto);
        visitCount(visitDto);
        visitAllCount(visitDto);
        articleCount(visitDto);

        return R.success(visitDto, "查询成功");
    }

    @Override
    public R<WeekDto> weekData() {
        List<Visitcount> visitcounts = visitcountMapper.SevenDaysVisitCount();
        WeekDto weekDto = new WeekDto();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        weekDto.setDate(visitcounts.stream().
                map(obj -> obj.getCreateTime().format(formatter)).
                toArray(String[]::new));
        weekDto.setCount(visitcounts.stream().map(Visitcount::getVCount).toArray(Integer[]::new));
        return R.success(weekDto, "查询成功");
    }

    // 检查 ip 是否在redis
    public VisitDto checkIp(HttpServletRequest httpServletRequest, VisitDto visitDto) {
        String ip = httpServletRequest.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = httpServletRequest.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = httpServletRequest.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = httpServletRequest.getRemoteAddr();
        }
        if (!redisUtils.exists(ip)) {
            if (!redisUtils.Tset(ip, "1", 15)) {
                return visitDto;
            }
            if (redisUtils.exists(VISIT_COUNT_KEY)) {
                redisUtils.set(VISIT_COUNT_KEY, Integer.parseInt(redisUtils.get(VISIT_COUNT_KEY)+"")+1+"");
                return visitDto;
            }
            visitDto.setVisitCount(1);
        }
        return visitDto;
    }

    // 每日访问量
    public void visitCount(VisitDto visitDto) {
        if (redisUtils.exists(VISIT_COUNT_KEY)) {
            visitDto.setVisitCount(Integer.parseInt(redisUtils.get(VISIT_COUNT_KEY)+""));
        } else {
            LambdaQueryWrapper<Visitcount> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(Visitcount::getCreateTime, LocalDate.now());
            Visitcount one = visitcountMapper.selectOne(queryWrapper);
            if (one != null) {
                visitDto.setVisitCount(one.getVCount() + visitDto.getVisitCount());
            }
            redisUtils.set(VISIT_COUNT_KEY, visitDto.getVisitCount()+"");
        }
    }

    // 总访问量
    public void visitAllCount(VisitDto visitDto) {
        if (redisUtils.exists(VISIT_ALL_COUNT_KEY)) {
            visitDto.setVisitAllCount(Integer.parseInt(redisUtils.get(VISIT_ALL_COUNT_KEY)+"") + visitDto.getVisitCount());
        } else {
            Integer count = visitcountMapper.getAllVisitCount(LocalDate.now());
            visitDto.setVisitAllCount(count + visitDto.getVisitCount());
        }
    }

    // 文章总数
    public void articleCount(VisitDto visitDto) {
        if (redisUtils.exists(ARTICLE_COUNT_KEY)) {
            visitDto.setArticleCount(Integer.parseInt(redisUtils.get(ARTICLE_COUNT_KEY)+""));
        } else  {
            visitDto.setArticleCount(articleService.count());
            redisUtils.set(ARTICLE_COUNT_KEY, visitDto.getArticleCount()+"");
        }
    }
}




